import React, {PureComponent} from "react";

import {PageHeaderWrapper} from "@ant-design/pro-layout";
import {Button, Card, Col, Divider, Drawer, Form, Input, Pagination, Progress, Row, Select, Switch, Tag} from "antd";
import convertMarkDown from "@/utils/marked";
import debounce from 'lodash/debounce';
import {
  UnorderedListOutlined, RetweetOutlined
} from '@ant-design/icons'
import {connect} from "umi";

const {Option} = Select;

class MemCard extends PureComponent {
  state = {
    drawerVisible: false,
    drawerData: null,
    total: 0,
    pageVO: {
      opt: "REVIEW",
      page: 0,
      size: 20,
      param: null,
      orders: 'desc',
    }
  }


  page = () => {
    const dispatch = this.props.dispatch;
    dispatch({
      type: 'memCard/page',
      payload: this.state.pageVO,
    });
  }

  save = data => {
    const dispatch = this.props.dispatch;
    dispatch({
      type: 'memCard/save',
      payload: data,
    });
  }

  level = id => {
    const dispatch = this.props.dispatch;
    dispatch({
      type: 'memCard/level',
      payload: {id: id},
    });
  }
  deleteCard = id => {
    const dispatch = this.props.dispatch;
    dispatch({
      type: 'memCard/deleteCard',
      payload: {id: id},
    });
  }

  reset = id => {
    const dispatch = this.props.dispatch;
    dispatch({
      type: 'memCard/reset',
      payload: {id: id},
    });
  }


  //
  cardCallBack(option, data) {
    let id = data.card.cardId;

    if ("Reminded" == option) {
      this.level(id);
      this.page();
    } else if ("Forget" == option) {
      this.reset(id);
      this.page();
    } else if ("Edit" == option) {
      this.openDrawer(data);
    } else if ("Delete" == option) {

      this.deleteCard(id);
      this.page();
    }
  }

  setOrders(v) {

    this.state.pageVO.orders = v ? "desc" : "asc";
  }

  setOpt(mode) {
    let pageVO1 = {
      opt: mode,
      page: 0,
      size: 20,
      param: null,
      orders: 'desc',
    }
    this.state.pageVO = pageVO1;
    this.page();
  }

  openDrawer(data) {
    this.setState({drawerVisible: true, drawerData: data});
  }

  drawerCallBack(option, data) {

    if (option == "Submit") {

      this.save(data);

    }
    this.setState({drawerVisible: false});
  }

  onPaginationChange(num, size) {
    this.state.pageVO.page = num - 1;
    this.state.pageVO.size = size;
    this.page();
  }

  componentDidMount() {
    this.page();
  }

  render() {
    let data = this.props.memCard.page;


    return (
      <PageHeaderWrapper>
        <MyDrawer
          data={this.state.drawerData}
          visible={this.state.drawerVisible}
          callback={(option, data) => {
            this.drawerCallBack(option, data);
          }}></MyDrawer>
        <Card>
          <Switch checkedChildren="倒序" unCheckedChildren="正序" defaultChecked onChange={v => this.setOrders(v)}></Switch>
          <Button onClick={() => this.openDrawer({})}>Add New Card</Button>

          <Select value={this.state.pageVO.opt} onChange={(v) => this.setOpt(v)}>
            <Select.Option value={"REVIEW"}>Review Mode</Select.Option>
            <Select.Option value={"TAG"}>Tag Mode</Select.Option>
            <Select.Option value={"ALL"}>All Mode</Select.Option>
          </Select>


          {this.state.pageVO.opt == 'TAG' ?
            (<Select defaultValue={"TAG 1"}>
              <Select.Option value={"TAG 1"}>TAG 1</Select.Option>
              <Select.Option value={"TAG 2"}>TAG 2</Select.Option>
              <Select.Option value={"TAG 3"}>TAG 3</Select.Option>
            </Select>)
            : ""
          }
          <h3>&nbsp;</h3>
          <Pagination showQuickJumper showSizeChanger defaultCurrent={1}
                      total={this.props.memCard.page.totalElements}
                      defaultPageSize={20}
                      onChange={this.onPaginationChange}/>


        </Card>
        <Row>
          {data.content.map((item, index) => (
              <MyCard data={item} key={`card${index}`} callback={(d, f) => {
                this.cardCallBack(d, f);
              }}>

              </MyCard>
            )
          )}

        </Row>
      </PageHeaderWrapper>
    )
  }
}

class MyDrawer extends PureComponent {
  data = {}

  onClose = (option) => {
    if (this.props.callback) {
      this.props.callback(option, this.data);
    }

  };
  onChange = e => {
    let target = e.currentTarget;
    let value = target.value;
    let name = target.id;
    this.data.card[name] = value;
  }

  render() {
    this.data = this.props.data && JSON.stringify(this.props.data) != JSON.stringify({}) ? this.props.data : {
      card: {},
      tags: []
    };
    if (JSON.stringify(this.data.card) == JSON.stringify({})) {
      this.data.card = {
        orders: (new Date()).valueOf(),
        level: 0,
        lastReviewTime: new Date()
      }
    }
    let card = this.data.card;

    return (<Drawer
      title={card.id == null ? "Add New Card" : "Edit Card"}
      width={720}
      onClose={() => this.onClose('Close')}
      placement={"right"}
      visible={this.props.visible}
      bodyStyle={{paddingBottom: 80}}
      footer={
        <div
          style={{
            textAlign: 'right',
          }}
        >

        </div>

      }
      destroyOnClose
    >
      <Form layout="vertical" hideRequiredMark
            onFinish={(data) => {

              this.onClose("Submit")
            }}
            initialValues={{
              orders: card.orders
            }}
      >
        <Row gutter={16}>
          <Col span={24}>
            <Form.Item
              name="title"
              label="Title"
              rules={[
                {
                  required: true,
                  message: 'please enter the title',
                },
              ]}

            >
              <Input rows={4} defaultValue={card.title} onChange={this.onChange}
                     placeholder="please enter the title"/>
            </Form.Item>
          </Col>
        </Row>
        <Row>
          <Col span={24}>
            <Form.Item

              label="Description"
              rules={[
                {
                  required: true,
                  message: 'please enter the detail',
                },
              ]}
            >
              <Input.TextArea id={"text"} rows={20} onChange={this.onChange} cols={100}
                              placeholder="please enter the detail" defaultValue={card.text}></Input.TextArea>
            </Form.Item>
          </Col>
        </Row>
        <Row>
          <Col span={24}>
            <Form.Item

              label="Tips"
            >
              <Input.TextArea id={"tips"} rows={4} onChange={this.onChange}
                              placeholder="please enter  tips" defaultValue={card.tips}></Input.TextArea>
            </Form.Item>
          </Col>
        </Row>
        <Row>

          <Col span={6}>
            <Form.Item
              name="orders"
              label="Order"

            >

              <Input type={'number'} id={"orders"} rows={4} onChange={this.onChange} defaultValue={card.orders}
                     placeholder="order"/>,

            </Form.Item>

          </Col>
          <Col span={1}>
          </Col>
          <Col span={4}>
            <Form.Item
              name="extra0"
              label="Level"
            >
              <Input type={'number'} disabled={true} rows={4} defaultValue={card.level}/>
            </Form.Item>
          </Col>
          <Col span={1}>
          </Col>
          <Col span={6}>
            <Form.Item
              name="extra1"
              label="Last Review Time"
            >
              <Input type={'text'} disabled={true} rows={4}
                     defaultValue={card.lastReviewTime ? card.lastReviewTime.toLocaleString() : ''}/>
            </Form.Item>
          </Col>
        </Row>
        <Form.Item>
          <Row>
            <Button onClick={() => this.onClose('Cancel')} style={{marginRight: 8}}>
              Cancel
            </Button>
            <Button type="primary" htmlType="submit">
              Submit
            </Button>
          </Row>
        </Form.Item>
      </Form>
    </Drawer>);
  }
}

class MyCard extends PureComponent {
  state = {
    expand: null,
  }


  flipSide() {
    this.setState({expand: !this.state.expand});
  }


  callback(option) {

    if (this.props.callback) {
      this.props.callback(option, this.props.data);
    }
  }

  render() {
    //默认处理data
    let data = this.props.data.card;
    if (data == null) {
      data = {}
    }
    //处理默认展开状态
    if (this.state.expand == null) {
      this.state.expand = this.props.data.expand;
      if (this.state.expand == null) {
        this.state.expand = false;
      }
    }
    let reviewProgress = data.level ? parseInt((100 / 7 * data.level)) : 0;
    return (
      <Col span={this.state.expand ? 24 : 6}>
        <Card title={data.title}

              extra={<>
                <RetweetOutlined onClick={() => this.flipSide()}/>&nbsp;
                <UnorderedListOutlined onClick={
                  () => this.callback("Edit")
                }/>
              </>}
              refresh={this.props.refresh}
        >

          <div>
            {this.state.expand ?
              (<div dangerouslySetInnerHTML={{__html: data.text != null ? convertMarkDown(data.text) : ""}}></div>) :
              (<div>
                <p>[Tips]: {data.tips}</p>
                <Progress percent={reviewProgress}/>
                <h3>&nbsp;</h3>
                <Tag color={'green'}>State {data.state}</Tag>
              </div>)
            }
          </div>

          <Divider>

          </Divider>
          <div style={{float: "right"}}>
            <Button onClick={
              () => this.callback("Reminded")
            }>Reminded</Button>&nbsp;
            <Button onClick={
              () => this.callback("Forget")
            }>Forget</Button>
            <Button onClick={
              () => this.callback("Delete")
            }>Delete</Button>
          </div>
        </Card>
      </Col>
    );
  }
}

class SearchSelect extends PureComponent {
  constructor(props) {
    super(props);
    this.lastFetchId = 0;
    this.fetchData = debounce(this.fetchData, 800);
  }

  state = {
    data: [],
    value: [],
    fetching: false,
  };

  fetchData = value => {

    this.lastFetchId += 1;
    const fetchId = this.lastFetchId;
    this.setState({data: [], fetching: true});
    fetch('https://randomuser.me/api/?results=5')
      .then(response => response.json())
      .then(body => {
        if (fetchId !== this.lastFetchId) {
          // for fetch callback order
          return;
        }
        const data = body.results.map(user => ({
          text: `${user.name.first} ${user.name.last}`,
          value: user.login.username,
        }));
        this.setState({data, fetching: false});
      });
  };

  handleChange = value => {
    this.setState({
      value,
      data: [],
      fetching: false,
    });
  };

  render() {
    const {fetching, data, value} = this.state;
    return (
      <Select
        mode="multiple"
        labelInValue
        value={value}
        placeholder="Select users"
        notFoundContent={fetching ? <Spin size="small"/> : null}
        filterOption={false}
        onSearch={this.fetchData}
        onChange={this.handleChange}
        style={{width: '100%'}}
      >
        {data.map(d => (
          <Option key={d.value}>{d.text}</Option>
        ))}
      </Select>
    );
  }
}

export default connect(({memCard, loading}) => ({
  memCard: memCard,
}))(MemCard);
